package com.gitee.melin.bee.core.jdbc.parser;

import static com.gitee.melin.bee.core.jdbc.enums.DataSourceType.*;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Logger;

public class JdbcURLParser {
    private static final Logger LOG = Logger.getLogger(JdbcURLParser.class.getName());

    private static final String MYSQL_JDBC_URL_PREFIX = "jdbc:mysql";

    private static final String ORACLE_JDBC_URL_PREFIX = "jdbc:oracle";

    private static final String POSTGRESQL_JDBC_URL_PREFIX = "jdbc:postgresql";

    private static final String MARIADB_JDBC_URL_PREFIX = "jdbc:mariadb";

    private static final String SQLSERVER_JDBC_URL_PREFIX = "jdbc:sqlserver";

    private static final String DB2_JDBC_URL_PREFIX = "jdbc:db2";

    private static final String SNOWFLAKE_JDBC_URL_PREFIX = "jdbc:snowflake";

    private static final String CLICKHOUSE_JDBC_URL_PREFIX = "jdbc:clickhouse";

    private static final String REDSHIFT_JDBC_URL_PREFIX = "jdbc:redshift";

    private static final String KINGBASEES_JDBC_URL_PREFIX = "jdbc:kingbase8";

    private static final Map<String, ConnectionURLParser> parserRegister = new LinkedHashMap<>();

    static {
        // put mysql parser firstly
        parserRegister.put(MYSQL_JDBC_URL_PREFIX, new MysqlURLParser());
        parserRegister.put(ORACLE_JDBC_URL_PREFIX, new OracleURLParser());
        parserRegister.put(MARIADB_JDBC_URL_PREFIX, new MariadbURLParser());
        parserRegister.put(SQLSERVER_JDBC_URL_PREFIX, new SqlServerURLParser());
        parserRegister.put(DB2_JDBC_URL_PREFIX, new DB2URLParser());
        parserRegister.put(SNOWFLAKE_JDBC_URL_PREFIX, new SnowflakeURLParser());
        parserRegister.put(CLICKHOUSE_JDBC_URL_PREFIX, new ClickhouseURLParser());

        parserRegister.put(POSTGRESQL_JDBC_URL_PREFIX, new PostgreSQLURLParser(POSTGRESQL));
        parserRegister.put(REDSHIFT_JDBC_URL_PREFIX, new PostgreSQLURLParser(REDSHIFT));
        parserRegister.put(KINGBASEES_JDBC_URL_PREFIX, new PostgreSQLURLParser(KINGBASEES));
    }

    /** parse the url to the ConnectionInfo */
    public static JdbcURLInfo parse(String url) {
        if (null == url) {
            return null;
        }
        String lowerCaseUrl = url.toLowerCase();
        ConnectionURLParser parser = findURLParser(lowerCaseUrl);
        if (parser == null) {
            throw new IllegalArgumentException("not support ds url: " + url);
        }
        return parser.parse(url);
    }

    private static ConnectionURLParser findURLParser(String lowerCaseUrl) {
        for (Map.Entry<String, ConnectionURLParser> entry : parserRegister.entrySet()) {
            if (lowerCaseUrl.startsWith(entry.getKey())) {
                return entry.getValue();
            }
        }
        return null;
    }

    /** register new ConnectionURLParser. Can override existing parser. */
    public static void registerConnectionParser(String urlPrefix, ConnectionURLParser parser) {
        if (null == urlPrefix || parser == null) {
            throw new IllegalArgumentException("urlPrefix and parser can not be null");
        }
        parserRegister.put(urlPrefix.toLowerCase(), parser);
    }
}
